package com.launch.imscore.controller;

import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;


/**
 * 说明 :
 *
 * @author zhongbo
 * @date 2019年09月05日
 */
@RequestMapping("/")
@Controller
public class FileController {

    Logger log = LoggerFactory.getLogger(FileController.class);

    String fileDir;
    private static String SEPARATOR = File.separator;

    private static FileFilter filter = new FileFilter() {
        public boolean accept(File pathname) {
            boolean directory = pathname.isDirectory();
            boolean hidden = pathname.isHidden();
            boolean exists = pathname.exists();
            return !directory && !hidden && !exists;
        }
    };
    private Object file;

    @Value("${file.dir}")
    public void setFileDir(String fileDir) {
        this.fileDir = fileDir;
        File file = new File(fileDir);
        if (!file.exists()) {
            boolean mkdirs = file.mkdirs();
            if (!mkdirs) {
                throw new RuntimeException(String.format("can not mkdirs for : %s", fileDir));
            }
        } else if (file.isFile()) {
            throw new RuntimeException(String.format("the fileDir is not a dir : %s", fileDir));
        }
    }

    @RequestMapping
    @ResponseBody
    public Object file(HttpServletRequest req, HttpServletResponse resp, String get, String del, MultipartFile file) {
        if (get != null) {
            return getFile(resp, get);
        }
        if (del != null) {
            return delFile(resp, del);
        }
        Boolean upFile = upFile(file);
        return listFile(upFile);
    }

    private Object listFile(Boolean upFile) {
        File dir = new File(fileDir);
        File[] files = dir.listFiles();
        StringBuilder sb = new StringBuilder();
        if (upFile != null && upFile) {
            //<meta http-equiv="Refresh" content="3" />
            sb.append("<meta http-equiv='Refresh' content='3'/>\n");
        }
        sb.append("<hr>" +
                "<form method='POST' enctype='multipart/form-data'>\n" +
                "<span>选择文件</span>\n" +
                "<input type='file' name='file'>\n" +
                "<button type='submit'>提交</button>\n" +
                "</form>\n");
        if (files != null && files.length > 0) {
            if (upFile != null) {
                sb.append(String.format("<p>upFile : %s</p>\n", upFile));
            }
            sb.append("<ul>\n");
            for (File showFile : files) {
                //<li><a href="?get=%s" target="_blank">%s</a></li>\n
                String aEle = String.format("<li><a href='?get=%s' target='_blank'>%s</a> | <a href='?del=%s' target='_self'>[删除]</a></li>\n", showFile.getName(), showFile.getName(), showFile.getName());
                sb.append(aEle);
            }
            sb.append("</ul>\n");
            return sb.toString();
        } else {
            sb.append("<p>no-file</p>");
        }
        return sb.toString();
    }

    private Boolean upFile(MultipartFile file) {
        if (file != null) {
            InputStream in = null;
            FileOutputStream out = null;
            try {
                String name = file.getOriginalFilename();
                String outPath = fileDir + SEPARATOR + name;
                in = file.getInputStream();
                File outFile = new File(outPath);
                if (outFile.exists()) {
                    return false;
                }
                out = new FileOutputStream(outFile);
                int copy = IOUtils.copy(in, out);
                if (copy > 0) {
                    return true;
                } else {
                    boolean delete = outFile.delete();
                    return false;
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (out != null) {
                        out.close();
                    }
                    if (in != null) {
                        in.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    private Object delFile(HttpServletResponse resp, String del) {
        File delFile = new File(fileDir + "/" + del);
        if (delFile.exists() && delFile.isFile()) {
            try {
                boolean delete = delFile.delete();
                log.info(String.format("delete %s %s", delete, del));
                resp.sendRedirect("/");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    public Object getFile(HttpServletResponse resp, String get) {
        File getFile = new File(fileDir + "/" + get);
        if (getFile.exists() && getFile.isFile()) {
            ServletOutputStream out = null;
            FileInputStream in = null;
            try {
                resp.setContentType(MediaType.APPLICATION_OCTET_STREAM.toString());
                resp.addHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + getFile.getName());
                out = resp.getOutputStream();
                in = new FileInputStream(getFile);
                int copy = IOUtils.copy(in, out);
                if (copy <= 0) {
                    return "err";
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (in != null) {
                        in.close();
                    }
                    if (out != null) {
                        out.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }
}
